package models

import (
	"html/template"
	"io"
	"log"
	"time"
)

type TemplateBlog struct {
	*template.Template
}

type HTMLTemplate struct {
	Index      TemplateBlog
	Category   TemplateBlog
	Custom     TemplateBlog
	Detail     TemplateBlog
	Login      TemplateBlog
	Pigeonhole TemplateBlog
	Writing    TemplateBlog
}

func (t *TemplateBlog) WriteData(w io.Writer, data interface{}) {
	err := t.Execute(w, data)
	if err != nil {
		_, err = w.Write([]byte(err.Error()))
		if err != nil {
			log.Println("WriteData error", err)
			return
		}
	}
}

func (t *TemplateBlog) WriteError(w io.Writer, err error) {
	if err != nil {
		_, err = w.Write([]byte(err.Error()))
		if err != nil {
			log.Println("WriteError error", err)
			return
		}
	}
}

func InitTemplate(templateDir string) (HTMLTemplate, error) {
	tp, err := readTemplate(
		[]string{"index",
			"category",
			"custom",
			"detail",
			"login",
			"pigeonhole",
			"writing"},
		templateDir)

	var htmlTemplate HTMLTemplate
	if err != nil {
		return htmlTemplate, err
	}
	htmlTemplate = HTMLTemplate{
		Index:      tp[0],
		Category:   tp[1],
		Custom:     tp[2],
		Detail:     tp[3],
		Login:      tp[4],
		Pigeonhole: tp[5],
		Writing:    tp[6],
	}

	return htmlTemplate, nil

}

func IsODD(num int) bool {
	return num%2 == 0
}

func GetNextName(str []string, index int) string {
	return str[index+1]
}

func Date(layout string) string {
	return time.Now().Format(layout)
}

func DateDay(date time.Time) string {
	return date.Format("2006-01-02 15:04:05")
}

func readTemplate(templates []string, templateDir string) ([]TemplateBlog, error) {
	var tbs []TemplateBlog
	for _, view := range templates {
		viewName := view + ".html"
		t := template.New(viewName)

		home := templateDir + `home.html`
		header := templateDir + `layout\header.html`
		footer := templateDir + `layout\footer.html`
		personal := templateDir + `layout\personal.html`
		pagination := templateDir + `layout\pagination.html`
		post := templateDir + `layout\post-list.html`

		// function mapping
		t.Funcs(template.FuncMap{
			"isODD":       IsODD,
			"getNextName": GetNextName,
			"date":        Date,
			"dateDay":     DateDay,
		})
		t, err := t.ParseFiles(
			templateDir+viewName,
			home,
			header,
			footer,
			personal,
			pagination,
			post,
		)
		if err != nil {
			log.Println("解析template.	..")
			log.Println(err)
			return nil, err
		}

		tb := TemplateBlog{
			Template: t,
		}
		tbs = append(tbs, tb)
	}
	return tbs, nil
}
